import irrlicht;

class CSampleSceneNode : ISceneNode
{
	SMaterial Material;
    FloatAABBox3D Box;
    
    S3DVertex[4] Vertices;
	
	this(ISceneNode parent, ISceneManager mgr, int id)
	{
        super(parent, mgr, id);
        
		Material = new SMaterial();
		Material.Wireframe = false;
		Material.Lighting = false;
        
		Vertices[0] = new S3DVertex(0,0,10,1,1,0, new SColor(255, 0, 255, 255), 0, 1);
		Vertices[1] = new S3DVertex(10,0,-10,1,0,0, new SColor(255, 255, 0, 255), 1,1);
        Vertices[2] = new S3DVertex(0, 20, 0, 0, 1,1, new SColor(255, 255, 255, 0), 1,0);
        Vertices[3] = new S3DVertex(-10, 0, -10, 0, 0, 1, new SColor(255, 0, 255, 0), 0, 0);
        
        Box = new FloatAABBox3D();
        Box.reset(Vertices[0].Pos);
        for(int i = 1; i<4; ++i)
            Box.addInternalPoint(Vertices[i].Pos);
    }
    
    override void OnRegisterSceneNode()
    {
        if(isVisible)
            SceneManager.registerNodeForRendering(this);
        super.OnRegisterSceneNode();  //  <-- Needed or not?
    }
    
    override void render()
    {
        ushort[] indices = [0,2,3,   2,1,3,   1,0,3,    2,0,1];
        IVideoDriver driver = SceneManager.getVideoDriver();
        
        driver.setMaterial(Material);
        driver.setTransform(E_TRANSFORMATION_STATE.ETS_WORLD, AbsoluteTransformation);
        driver.drawVertexPrimitiveList(Vertices, 4, indices, 4);
    }
    
    override const FloatAABBox3D getBoundingBox() const
    {
        return cast(FloatAABBox3D)Box;
    }
    
    override uint getMaterialCount() const
    {
        return 1;
    }
    
    override SMaterial getMaterial(uint i)
    {
        return Material;
    }
}

void main()
{
    //ask user for driver
    E_DRIVER_TYPE driverType = driverChoiceConsole();
    if(driverType == E_DRIVER_TYPE.EDT_COUNT)
        return;
        
    //create device
    
    IrrlichtDevice device = createDevice(driverType, new UintDimension2D(640, 480), 16, false, false, false, null);
    
    if(!device)
        return;
        
    device.setWindowCaption("Custom Scene Node - Irrlicht + D via SWIG Demo");
    
    IVideoDriver driver = device.getVideoDriver();
    ISceneManager smgr = device.getSceneManager();
    
    smgr.addCameraSceneNode(null, new FloatVector3D(0, -40, 0), new FloatVector3D(0, 0,0), -1, true);
    
    CSampleSceneNode myNode = new CSampleSceneNode(smgr.getRootSceneNode(), smgr, 666);
    ISceneNodeAnimator anim = smgr.createRotationAnimator(new FloatVector3D(0.8, 0, 0.8));
    
    if(anim)
    {
        myNode.addAnimator(anim);
        //anim.drop();  I found out, NEVER drop
        anim = null;
    }
    
    //myNode.drop();  don't do this
    myNode = null;
    
    uint frames = 0;
    
    while(device.run())
    {
        driver.beginScene(true, true, new SColor(0,100,100,100));
        smgr.drawAll();
        driver.endScene();
        
        if(++frames == 100)
        {
            auto str = "Irrlicht Engine (D via SWIG) ["w;
            str ~= std.conv.to!wstring(driver.getName());
		    str ~= "] FPS:";
			str ~= std.conv.to!wstring(driver.getFPS());
			device.setWindowCaption(str);
            frames = 0;
        }
    }
    device.drop();
    return;
}